using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Reflection;

namespace CreateDDF
{
    public class WriteManifestFile
    {
        private StreamWriter _stream;
        private XmlElement _featureManifests = null;
        string _assemblyName = string.Empty;
        XmlElement solutionElement = null;
		XmlElement resourcesElement = null;
		XmlElement rootFilesElement = null;

        public WriteManifestFile(string assemblyName)
        {
            this._assemblyName = assemblyName;
        }

        public StreamWriter Stream
        {
            get { return _stream; }
            set { _stream = value; }
        }

        private string _templateFilename;

        public string TemplateFilename
        {
            get { return _templateFilename; }
            set { _templateFilename = value; }
        }

        private string _path;

        public string Path
        {
            get { return _path; }
            set { _path = value; }
        }

        private XmlDocument template = null;


        public void CreateManifestFile()
        {
            string path = Environment.CurrentDirectory;
            DirectoryInfo currentDirectory = new DirectoryInfo(Environment.CurrentDirectory);
            
            DirectoryInfo debug = new DirectoryInfo(currentDirectory.FullName + "\\bin\\debug");

            

            
            string templatePath = this.Path + "TEMPLATE";

            this.template = new XmlDocument();
            this.template.PreserveWhitespace = true;
            this.template.Load(this.Path + this.TemplateFilename);

            solutionElement = template.DocumentElement;//.FirstChild;//.GetElementsByTagName("Solution");
    
            //XmlElement debugElement = this.template.CreateElement("Debug");

            string assemblyName = string.Empty;

            if(debug.Exists)
            {
                string assemblyPath = currentDirectory.FullName + "\\bin\\debug\\" + this._assemblyName;// +".dll";
                FileInfo fiAssembly = new FileInfo(assemblyPath);
                if (fiAssembly.Exists)
                {
                    Assembly assembly = System.Reflection.Assembly.LoadFile(assemblyPath);
                    assemblyName = assembly.FullName;
                }
            }

            

            resourcesElement = solutionElement.SelectSingleNode("Resources") as XmlElement;
			if (resourcesElement == null)
				resourcesElement = this.template.CreateElement("Resources", null);

			rootFilesElement = solutionElement.SelectSingleNode("RootFiles") as XmlElement;
			if (rootFilesElement == null)
				rootFilesElement = this.template.CreateElement("RootFiles", null);

            XmlElement templateFiles = solutionElement.SelectSingleNode("TemplateFiles") as XmlElement;
            if (templateFiles == null)
            {
                templateFiles = this.template.CreateElement("TemplateFiles");//, null);
            }

            _featureManifests = solutionElement.SelectSingleNode("FeatureManifests") as XmlElement;
            if (_featureManifests == null)
                _featureManifests = this.template.CreateElement("FeatureManifests");

            DirectoryInfo templateDirectory = new DirectoryInfo(templatePath);

            //WalkDirsForAssemblies(templateDirectory);

            WalkDirsForTemplateFiles(templateFiles, templateDirectory);

			solutionElement.InsertAfter(resourcesElement, solutionElement.LastChild);

            //solutionElement.InsertAfter(resources, solutionElement.LastChild);
            solutionElement.InsertAfter(templateFiles, solutionElement.LastChild);
            solutionElement.InsertAfter(_featureManifests, solutionElement.LastChild);

			solutionElement.InsertAfter(rootFilesElement, solutionElement.LastChild);
            //solutionElement.InsertAfter(debugElement, solutionElement.LastChild);

            string xml = this.template.OuterXml;
            xml = xml.Replace(" xmlns=\"\"", "");
            xml = xml.Replace("<TemplateFiles />", "");
            xml = xml.Replace("<FeatureManifests />", "");
			xml = xml.Replace("<FeatureManifests />", "");
			xml = xml.Replace("<RootFiles />", "");
			xml = xml.Replace("<Resources />", "");
            xml = xml.Replace("[ThisAssemblyName]", assemblyName);

            XmlDocument preWriteXML = new XmlDocument();
            preWriteXML.LoadXml(xml);
            preWriteXML.PreserveWhitespace = true;

            //StreamWriter SW;
            string writePath = this.Path + "manifest.xml";
            //SW.Write(xml);

            //FileInfo checkFile = new FileInfo(writePath);
            //if (checkFile.Exists)
            //    checkFile.Delete();

            FileStream fsxml = new FileStream(writePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
            preWriteXML.Save(fsxml);

            //XmlTextWriter manifest = new XmlTextWriter(this.Path + "Manifest.xml", null);
            //manifest.Formatting = Formatting.Indented;
            //template.WriteContentTo(manifest);
        }

        

        private void WalkDirsForTemplateFiles(XmlElement templateFiles, DirectoryInfo directory)
        {
            
            List<string> excludedFileTypes = new List<string>();
            excludedFileTypes.Add(".CS");
            excludedFileTypes.Add(".SCC");
            excludedFileTypes.Add(".RESX");
            excludedFileTypes.Add(".EXCLUDE");
			excludedFileTypes.Add(".SOURCE");
			excludedFileTypes.Add(".SPSOURCE");
			excludedFileTypes.Add(".PROVISIONHELPER");

            List<string> excludedDirectories = new List<string>();
            excludedDirectories.Add("LISTTEMPLATES");
            excludedDirectories.Add("RESOURCES");

            if (directory.Name.ToUpper().IndexOf(".EXCLUDE") != -1)
                return;

            if (directory.Parent.Name.ToUpper() != "FEATURES" && !excludedDirectories.Contains(directory.Name.ToUpper()))
            {
                FileInfo[] files = directory.GetFiles();
                if (files.Length > 0)
                {

                    foreach (FileInfo file in files)
                    {
                        if (excludedFileTypes.Contains(file.Extension.ToUpper()))
                            continue;

                        string fileFullName = file.FullName.Replace(this.Path, "");
                        string writeFile = fileFullName.Replace("TEMPLATE\\", "");
                        string parentName = directory.Parent.Name;
                        if (parentName.ToUpper() == "FEATURES")
                            writeFile = writeFile.Replace(parentName + "\\", "");

                        XmlElement templateFile = this.template.CreateElement("TemplateFile");
                        //<TemplateFile Location="LAYOUTS\GECMSV2Pages\Word\OutputWord.aspx"/>
                        XmlAttribute location = this.template.CreateAttribute("Location");
                        location.Value = writeFile;

                        templateFile.SetAttributeNode(location);
                        templateFiles.InsertAfter(templateFile, templateFiles.LastChild);

                        //if (directory.Name.ToUpper() == "RESOURCES")
                        //{
                        //    writeFile = writeFile.Replace("FEATURES\\", "");
                        //    writeFile = writeFile.Replace("RESOURCES\\", "");
                        //    //sw.WriteLine("\"" + fileFullName + "\" \"" + writeFile + "\"");
                        //    writeFile = "RESOURCES\\" + file.Name;
                        //}

                        //if (directory.Name.ToUpper() == "LISTTEMPLATES")
                        //{
                        //    writeFile = writeFile.Replace("FEATURES\\", "");
                        //}
                    }
                }
            }
            else if (directory.Parent.Name.ToUpper() == "FEATURES")
            {
                FileInfo[] files = directory.GetFiles();
                foreach (FileInfo file in files)
                {
                    if (file.Name.ToUpper() == "FEATURE.XML")
                    {
                        XmlElement featureManifest = this.template.CreateElement("FeatureManifest");
                        XmlAttribute location = this.template.CreateAttribute("Location");
                        location.Value = directory.Name + "\\" + file.Name;
                        featureManifest.SetAttributeNode(location);
                        _featureManifests.InsertAfter(featureManifest, _featureManifests.LastChild);
                    }
                }
            }

			FileInfo[] resxFiles = directory.GetFiles("*.resx");
			if (resxFiles.Length > 0)
			{
				foreach (FileInfo resxFile in resxFiles)
				{
					XmlElement rootFile = this.template.CreateElement("RootFile");
					XmlAttribute rfLocation = this.template.CreateAttribute("Location");
					rfLocation.Value = "Resources\\" + resxFile.Name;
					rootFile.SetAttributeNode(rfLocation);
					rootFilesElement.InsertAfter(rootFile, rootFilesElement.LastChild);

					XmlElement resource = this.template.CreateElement("Resource");
					XmlAttribute resLocation = this.template.CreateAttribute("Location");
					resLocation.Value = "Resources\\" + resxFile.Name;
					resource.SetAttributeNode(resLocation);
					resourcesElement.InsertAfter(resource, resourcesElement.LastChild);
				}
			}

            DirectoryInfo[] dirs = directory.GetDirectories();
            foreach (DirectoryInfo dir in dirs)
            {
                WalkDirsForTemplateFiles(templateFiles, dir);//, , dir, path);
            }
        }

    }
}

